/*
 * MIT License
 *
 * Copyright (c) 2024-2048 冰羽
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package cn.star.framework.type;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.star.framework.core.api.Pageable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import lombok.Getter;

/**
 * 解析 <span style='color: red;'>使用``包裹的均为变量</span><br>
 *
 * <table style='background-color: #654321; color: black'>
 *   <tr>
 *     <th>参数类型</th><th>请求参数</th><th>值</th>
 *   </tr>
 *   <tr>
 *     <td>Where</td>
 *     <td>
 *       <ul>
 *         <li>W.`field`.`{@link QueryType}`</li>
 *       </ul>
 *     </td>
 *     <td>
 *       <ul>
 *         <li>value | value[]</li>
 *       </ul>
 *     </td>
 *   </tr>
 *   <tr>
 *     <td>WhereGroup</td>
 *     <td>
 *       <ul>
 *         <li>G.`whereGroupName`.`field`.`{@link QueryType}`</li>
 *         <li>G.`whereGroupName`.operator</li>
 *         <li>G.`whereGroupName`.order</li>
 *       </ul>
 *     </td>
 *     <td>
 *       <ul>
 *         <li>value | value[]</li>
 *         <li>AND &nbsp;&nbsp;| OR</li>
 *         <li>number</li>
 *       </ul>
 *     </td>
 *   </tr>
 *   <tr>
 *     <td>Sorter</td>
 *     <td>
 *       <ul>
 *         <li>S.asc</li>
 *         <li>S.desc</li>
 *       </ul>
 *     </td>
 *     <td>
 *       <ul>
 *         <li>field, ... , field | field[]</li>
 *         <li>field, ... , field | field[]</li>
 *       </ul>
 *     </td>
 *   </tr>
 *   <tr>
 *     <td>QueryColumns</td>
 *     <td>
 *       <ul>
 *         <li>Q.columns</li>
 *       </ul>
 *     </td>
 *     <td>
 *       <ul>
 *         <li>field, ... , field | field[]</li>
 *       </ul>
 *     </td>
 *   </tr>
 *   <tr>
 *     <td>
 *       {@link Pageable}
 *     </td>
 *     <td>
 *       <ul>
 *         <li>P.pageNo</li>
 *         <li>P.pageSize</li>
 *       </ul>
 *     </td>
 *     <td>
 *       <ul>
 *         <li>1</li>
 *         <li>20</li>
 *       </ul>
 *     </td>
 *   </tr>
 *   <tr>
 *     <td>X(<a href=''>Unknown</a>)</td>
 *     <td>
 *       <ul>
 *         <li>X.ignoreReadeColumns</li>
 *         <li>X.ignoreWriteColumns</li>
 *         <li>X.normalQueryValue</li>
 *         <li>X.dataTreeType</li>
 *       </ul>
 *     </td>
 *     <td>
 *       <ul>
 *         <li>field, ... , field | field[]</li>
 *         <li>field, ... , field | field[]</li>
 *         <li>value</li>
 *         <li>sync|async</li>
 *       </ul>
 *     </td>
 *   </tr>
 * </table>
 *
 * @author zhaoweiping
 *     <p style='color: red'>Created on 2024-09-23 11:06:00
 * @since 3.0.0
 */
public enum MvcPrefixMark {
  /** 条件 */
  W("W", "w"),
  /** 条件(组) */
  G("G", "g"),
  /** 排序 */
  S("S", "s"),
  /** 查询字段 */
  Q("Q", "q"),
  /** 分页 */
  P("P", "p"),
  /** 其他 */
  X("X", "x"),
  ;

  /** 关键字 */
  public static final class Keywords {

    /** 组间连接符{@link BooleanOperator} */
    public static final String operator = "operator";

    /** 组的顺序号 */
    public static final String order = "order";

    /** 升序字段 */
    public static final String asc = "asc";

    /** 降序字段 */
    public static final String desc = "desc";

    /** 查询的列 */
    public static final String columns = "columns";

    /** 页码 */
    public static final String pageNo = "pageNo";

    /** 页数据 */
    public static final String pageSize = "pageSize";

    /** 导入时忽略的列 */
    public static final String ignoreReadeColumns = "ignoreReadeColumns";

    /** 导出时忽略的列 */
    public static final String ignoreWriteColumns = "ignoreWriteColumns";

    /** 全局查询的模糊值，需要根据数据类型获取{@link QueryType} */
    public static final String normalQueryValue = "normalQueryValue";

    /** {@link DataTreeType} */
    public static final String dataTreeType = "dataTreeType";
  }

  @Getter private final String[] values;

  MvcPrefixMark(String... prefix) {
    this.values = prefix;
  }

  public static List<String> wrapper(MvcPrefixMark mark, String... names) {
    List<String> list = new ArrayList<>();

    if (ArrayUtil.isNotEmpty(names)) {
      for (String name : names) {
        for (String value : mark.getValues()) {
          list.add(StrUtil.format("{}.{}", value, name));
        }
      }
      list.addAll(CollectionUtil.toList(names));
    }

    return list;
  }

  public static Set<String> getGroupNames(Map<String, ?> parameterMap) {
    Set<String> names = new HashSet<>(), parameterKeys = parameterMap.keySet();
    for (String key : parameterKeys) {
      String[] keys = key.split("\\.");
      if (ArrayUtil.isNotEmpty(keys) && keys.length >= 2) {
        String prefix = keys[0], name = keys[1];
        if (MvcPrefixMark.G.getValues()[0].equalsIgnoreCase(prefix)) {
          names.add(name);
        }
      }
    }

    return names;
  }
}
